package com.fate.service.impl;

import ch.qos.logback.core.pattern.color.MagentaCompositeConverter;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fate.dao.ProdEsDao;
import com.fate.es.ProdEs;
import com.fate.service.SearchService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.AbstractQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class SearchServiceImpl implements SearchService {
    /**
     * 复杂查询使用这个
     */
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;


    @Autowired
    private ProdEsDao prodEsDao;

    @Override
    public Page<ProdEs> findProdEsByTagId(Integer page, Integer size, Long tagId) {
        //做一个匹配查找
         TermQueryBuilder termQuery = QueryBuilders.termQuery("tagList", tagId);
            return query(page,size,termQuery,null,0);
     }

    @Override
    public Page<ProdEs> findProdEsByKeyword(Integer page, Integer size, String keywords, Integer sort) {
        MatchQueryBuilder matchQueryBuilder = null;
        if (StringUtils.hasText(keywords)){
            matchQueryBuilder = QueryBuilders.matchQuery("prodName", keywords);
        }
        return query(page,size,matchQueryBuilder,keywords,sort);
    }

    /**
     * 真正的查询方法
     */
    private Page<ProdEs> query(Integer page, Integer size, AbstractQueryBuilder queryBuilder,String keywords,Integer sort){
        //组装条件
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        //设置分页
        nativeSearchQueryBuilder.withPageable(PageRequest.of(page,size));
        //做排序
        SortBuilder sortBuilder = getSort(sort);
        nativeSearchQueryBuilder.withQuery(queryBuilder);
        //1.组装查询条件
        if (StringUtils.hasText(keywords)){
            HighlightBuilder.Field field = new HighlightBuilder.Field("prodName");
            field.preTags("<span style='color:red'>");
            field.postTags("</span>");
            // 高亮
            nativeSearchQueryBuilder.withHighlightFields(field);
        }
        //查询
        SearchHits<ProdEs> searchHits = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), ProdEs.class);
        ArrayList<ProdEs> prodEsArrayList = new ArrayList<>();
        //循环查询结果
        searchHits.forEach(searchHit ->{
            ProdEs prodEs = searchHit.getContent();
            //判断是否有是关键字查询
            List<String> prodNameList = searchHit.getHighlightField("prodName");
            if (!CollectionUtils.isEmpty(prodNameList)){
                String highName = prodNameList.get(0);
                if (StringUtils.hasText(highName)){
                    prodEs.setProdName(highName);
                }
            }
            prodEsArrayList.add(prodEs);
        });
        Page<ProdEs> prodEsPage = new Page<>(page + 1, size);
        prodEsPage.setTotal(searchHits.getTotalHits());
        prodEsPage.setRecords(prodEsArrayList);
        return prodEsPage;
    }
    /**
     * 排序的方法
     */
    private SortBuilder getSort(Integer sort){
        switch(sort){
            case 0:
                // 好评排序
                return SortBuilders.fieldSort("positiveRating").order(SortOrder.DESC);
            case 1:
                // 销量排序
                return SortBuilders.fieldSort("soldNum").order(SortOrder.DESC);
            case 2:
                // 价格排序
                return SortBuilders.fieldSort("price").order(SortOrder.ASC);
            default:
                throw new IllegalArgumentException("排序字段不允许");
        }
    }

    /**
     * 提供远程调用搜索服务根据ids搜索商品
     *
     * @param prodIds
     * @return
     */
    @Override
    public List<ProdEs> getProdEsByIds(List<Long> prodIds) {
        // 先查询es
        Iterable<ProdEs> prodEsIterable = prodEsDao.findAllById(prodIds);
        List<ProdEs> prodEsList = new ArrayList<>();
        prodEsIterable.forEach(prodEsList::add);
        return prodEsList;
    }
}
